package rule

import (
	"github.com/crazyhl/gopermission/models"
	"github.com/crazyhl/gopermission/service/permission"
	"github.com/gofiber/fiber/v2"
	"go-fiber-demo/pkg"
	"go-fiber-demo/pkg/db"
	"gorm.io/gorm/clause"
	"strconv"
)

// 添加角色
func Add(ctx *fiber.Ctx) error {
	rule := new(models.Rule)
	rule.Name = ctx.FormValue("name", "")
	rule.Description = ctx.FormValue("description", "")
	err := rule.Add()

	response := new(pkg.Response)
	if err != nil {
		if err.Error()[:db.ErrorDuplicateStrLength] == db.ErrorDuplicate {
			response.Status = -2
			response.Message = "已存在重复数据"
		} else {
			response.Status = -1
			response.Message = err.Error()
		}

		return ctx.JSON(response)
	}

	return ctx.JSON(rule)
}

// 更新角色
func Update(ctx *fiber.Ctx) error {
	ruleId := ctx.Params("id", "")
	gormDb := pkg.GetConfig().GormDb
	rule := new(models.Rule)

	gormDb.Where("id = ?", ruleId).First(&rule)
	response := new(pkg.Response)
	if rule.ID == 0 {
		response.Status = -1
		response.Message = "角色不存在"
		return ctx.JSON(response)
	}

	rule.Name = ctx.FormValue("name", "")
	rule.Description = ctx.FormValue("description", "")
	err := rule.Update()

	if err != nil {
		if err.Error()[:db.ErrorDuplicateStrLength] == db.ErrorDuplicate {
			response.Status = -2
			response.Message = "已存在重复数据"
		} else {
			response.Status = -1
			response.Message = err.Error()
		}

		return ctx.JSON(response)
	}

	return ctx.JSON(rule)
}

// 删除角色
func Delete(ctx *fiber.Ctx) error {
	ruleId := ctx.Params("id", "")
	gormDb := pkg.GetConfig().GormDb
	rule := new(models.Rule)

	gormDb.Where("id = ?", ruleId).First(&rule)
	response := new(pkg.Response)
	if rule.ID == 0 {
		response.Status = -1
		response.Message = "角色不存在"
		return ctx.JSON(response)
	}

	_, err := rule.Delete()

	if err != nil {
		response.Status = -1
		response.Message = err.Error()

		return ctx.JSON(response)
	}

	response.Message = "删除成功"

	return ctx.JSON(response)
}

// 角色详情
func Detail(ctx *fiber.Ctx) error {
	ruleId := ctx.Params("id", "")
	gormDb := pkg.GetConfig().GormDb
	rule := new(models.Rule)

	gormDb.Where("id = ?", ruleId).Preload(clause.Associations).First(&rule)
	response := new(pkg.Response)
	if rule.ID == 0 {
		response.Status = -1
		response.Message = "角色不存在"
		return ctx.JSON(response)
	}

	return ctx.JSON(rule)
}

// 角色列表
func List(ctx *fiber.Ctx) error {
	page, _ := strconv.Atoi(ctx.Query("page", "0"))
	pageSize, _ := strconv.Atoi(ctx.Query("size", "1"))
	// 防止页码溢出
	if page < 1 {
		page = 1
	}
	// 计算偏移
	offset := (page - 1) * pageSize

	rules := make([]models.Rule, 0)

	gormDb := pkg.GetConfig().GormDb
	gormDb.Limit(pageSize).Offset(offset).Order("id DESC").Find(&rules)
	var total int64
	gormDb.Model(&models.Rule{}).Count(&total)

	response := new(pkg.Response)
	response.Data = fiber.Map{
		"total": total,
		"data":  rules,
	}

	return ctx.JSON(response)
}

// 角色绑定权限
func AttachPermissions(ctx *fiber.Ctx) error {
	ruleId := ctx.Params("id", "")
	gormDb := pkg.GetConfig().GormDb
	rule := new(models.Rule)

	gormDb.Where("id = ?", ruleId).Preload(clause.Associations).First(&rule)
	response := new(pkg.Response)
	if rule.ID == 0 {
		response.Status = -1
		response.Message = "角色不存在"
		return ctx.JSON(response)
	}
	// 接收传入的 permissions id ，然后替换关联
	form, err := ctx.MultipartForm()
	if err != nil {
		response.Status = -2
		response.Message = err.Error()
		return ctx.JSON(response)
	}
	permissionIds := form.Value["permissions"]
	// 通过id 查找权限
	permissions := permission.FindByIdsString(permissionIds)

	err = gormDb.Model(&rule).Association("Permissions").Replace(permissions)

	if err != nil {
		response.Status = -3
		response.Message = err.Error()
		return ctx.JSON(response)
	}

	response.Message = "关联成功"

	return ctx.JSON(response)
}
